/**
 * gecodemodel.h is part of Gedule.
 *
 * Gedule is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Gedule is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Gedule.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef GECODEMODEL_H
#define GECODEMODEL_H

#include <gecode/int.hh>
#include "../utils/visitor/visitor.h"
#include "../utils/printable.h"
#include "../definitions.h"

class GecodeModel : public Gecode::Space, public Visitor, public Printable
{
public:
    GecodeModel( Model & a_model );

    GecodeModel( bool a_share, GecodeModel & a_other );

    virtual ~GecodeModel();

    bool Solve();

    virtual GecodeModel * copy( bool a_share );

    virtual std::string Print() const;

    virtual void Visit( Model * a_model );
    virtual void Visit( Task * a_task );
    virtual void Visit( Resource * a_resource );
    virtual void Visit( TimeWindow * a_constraint );
    virtual void Visit( Lenght * a_constraint );
    virtual void Visit( NeededResources * a_constraint );
    virtual void Visit( Capacity * a_constraint );
    virtual void Visit( Unavailabilities * a_constraint );
    virtual void Visit( AllowIdles * a_constraint );
    virtual void Visit( MaxTime * a_constraint );

private:

    // Fields
    // ------

    // Model parameters.
    tTime                       m_maxTime;
    std::vector< std::string >  m_tasksNames;
    std::vector< std::string >  m_resourcesNames;
    bool                        m_allowIdles;

    Gecode::IntArgs     m_capacities;
    Gecode::IntArgs     m_lenghts;
    Gecode::IntArgs     m_resourcesNeeded;
    Gecode::IntVarArgs  m_startTimesArgs;
    Gecode::IntVarArgs  m_endTimesArgs;
    Gecode::IntVarArray m_startTimesVars;
    Gecode::IntVarArray m_endTimesVars;

    // Methods
    // -------

    void InitVars();
    void PostConstraints();

    // Protect default copy constructor.
    GecodeModel( const GecodeModel & a_other );

    // Protect default operator =.
    GecodeModel & operator = ( const GecodeModel & a_other );
};

#endif // GECODEMODEL_H
